package learn_concurrent._11;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAdder;
import java.util.function.Consumer;
import java.util.function.Supplier;

public class LongAdderTest {
	
	public static void main(String[] args) {
		demo(
				() -> new AtomicLong(),
				atomicLong -> atomicLong.incrementAndGet()
				);
		
		demo(
				() -> new LongAdder(),
				longAdder -> longAdder.increment()
				);
	}
	
	static<T> void demo(Supplier<T> supplier, 
						Consumer<T> action) {
		T adder = supplier.get();
		List<Thread> threadList = new ArrayList<>();
		for (int i = 0; i < 4; i++) {
			threadList.add(
					new Thread(() -> {
						for (int j = 0; j < 500000; j++) {
							action.accept(adder);
						}
					})
					);
		}
		
		long start = System.nanoTime();
		threadList.forEach(Thread::start);
		threadList.forEach(t -> {
			try {
				t.join();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		});
		
		long end = System.nanoTime();
		
		System.out.println(adder.getClass().getName() + " : " + adder + " : cost : " + (end -start) / 1000_000);
	}

}
